using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using DocumentCreationSystem.Models;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 文件命名服务 - 统一管理所有文件的中文命名规则
    /// </summary>
    public interface IFileNamingService
    {
        /// <summary>
        /// 生成章节文件名
        /// </summary>
        string GenerateChapterFileName(string bookTitle, int volumeNumber, string volumeName, int chapterNumber, string chapterTitle, string fileExtension = ".txt");
        
        /// <summary>
        /// 生成大纲文件名
        /// </summary>
        string GenerateOutlineFileName(string bookTitle, string outlineType, string fileExtension = ".txt");
        
        /// <summary>
        /// 生成世界设定文件名
        /// </summary>
        string GenerateWorldSettingFileName(string bookTitle, string settingType, string fileExtension = ".txt");
        
        /// <summary>
        /// 生成角色设定文件名
        /// </summary>
        string GenerateCharacterFileName(string bookTitle, string characterName, string fileExtension = ".txt");
        
        /// <summary>
        /// 生成时间线文件名
        /// </summary>
        string GenerateTimelineFileName(string bookTitle, int? volumeNumber = null, string fileExtension = ".txt");
        
        /// <summary>
        /// 清理文件名中的非法字符
        /// </summary>
        string SanitizeFileName(string fileName);
        
        /// <summary>
        /// 获取中文文件夹名称映射
        /// </summary>
        Dictionary<string, string> GetChineseFolderNames();

        /// <summary>
        /// 获取当前文件命名配置
        /// </summary>
        FileNamingConfig GetCurrentConfig();

        /// <summary>
        /// 保存文件命名配置
        /// </summary>
        void SaveConfig(FileNamingConfig config);

        /// <summary>
        /// 使用配置生成章节文件名
        /// </summary>
        string GenerateChapterFileName(string bookTitle, int volumeNumber, string volumeName, int chapterNumber, string chapterTitle, string fileExtension, FileNamingConfig? config = null);

        /// <summary>
        /// 使用配置生成大纲文件名
        /// </summary>
        string GenerateOutlineFileName(string bookTitle, string outlineType, string fileExtension, FileNamingConfig? config = null);

        /// <summary>
        /// 使用配置生成角色文件名
        /// </summary>
        string GenerateCharacterFileName(string bookTitle, string characterName, string fileExtension, FileNamingConfig? config = null);

        /// <summary>
        /// 使用配置生成时间线文件名
        /// </summary>
        string GenerateTimelineFileName(string bookTitle, int? volumeNumber, string fileExtension, FileNamingConfig? config = null);
    }

    public class FileNamingService : IFileNamingService
    {
        private readonly ILogger<FileNamingService> _logger;
        private readonly string _configPath;
        private FileNamingConfig? _currentConfig;
        
        // 中文文件夹名称映射
        private readonly Dictionary<string, string> _chineseFolderNames = new()
        {
            { "Documents", "文档" },
            { "Resources", "资源" },
            { "Backup", "备份" },
            { "Export", "导出" },
            { "Chapters", "章节" },
            { "Characters", "角色设定" },
            { "Outlines", "大纲" },
            { "Settings", "世界设定" },
            { "Timeline", "时间线" },
            { "Plots", "情节设定" },
            { "Worldview", "世界观" },
            { "Maps", "地图" },
            { "Factions", "势力设定" },
            { "Items", "物品设定" },
            { "Skills", "技能设定" },
            { "Relationships", "关系网络" }
        };

        public FileNamingService(ILogger<FileNamingService> logger)
        {
            _logger = logger;
            _configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "FileNamingConfig.json");
        }

        /// <summary>
        /// 生成章节文件名
        /// 格式：书名_第X卷_卷名_第X章_章节名.扩展名
        /// </summary>
        public string GenerateChapterFileName(string bookTitle, int volumeNumber, string volumeName, int chapterNumber, string chapterTitle, string fileExtension = ".txt")
        {
            var fileName = new StringBuilder();

            // 书籍名称
            fileName.Append(SanitizeFileName(bookTitle));

            // 卷宗信息
            if (volumeNumber > 0)
            {
                fileName.Append($"_第{volumeNumber:D2}卷");
                if (!string.IsNullOrEmpty(volumeName))
                {
                    fileName.Append($"_{SanitizeFileName(volumeName)}");
                }
            }

            // 章节信息
            fileName.Append($"_第{chapterNumber:D3}章");
            if (!string.IsNullOrEmpty(chapterTitle))
            {
                fileName.Append($"_{SanitizeFileName(chapterTitle)}");
            }

            fileName.Append(fileExtension);
            return fileName.ToString();
        }

        /// <summary>
        /// 生成大纲文件名
        /// 格式：书名_大纲类型.扩展名
        /// </summary>
        public string GenerateOutlineFileName(string bookTitle, string outlineType, string fileExtension = ".txt")
        {
            var outlineTypeMap = new Dictionary<string, string>
            {
                { "overall", "总体大纲" },
                { "volume", "卷宗大纲" },
                { "chapter", "章节细纲" },
                { "character", "角色大纲" },
                { "plot", "情节大纲" }
            };

            var chineseType = outlineTypeMap.ContainsKey(outlineType.ToLower()) 
                ? outlineTypeMap[outlineType.ToLower()] 
                : outlineType;

            return $"{SanitizeFileName(bookTitle)}_{chineseType}{fileExtension}";
        }

        /// <summary>
        /// 生成世界设定文件名
        /// 格式：书名_设定类型.扩展名
        /// </summary>
        public string GenerateWorldSettingFileName(string bookTitle, string settingType, string fileExtension = ".txt")
        {
            var settingTypeMap = new Dictionary<string, string>
            {
                { "worldview", "世界观设定" },
                { "magic", "魔法体系" },
                { "cultivation", "修炼体系" },
                { "politics", "政治体系" },
                { "economy", "经济体系" },
                { "geography", "地理设定" },
                { "history", "历史背景" },
                { "culture", "文化设定" },
                { "technology", "科技设定" },
                { "religion", "宗教设定" },
                { "races", "种族设定" },
                { "factions", "势力设定" },
                { "items", "物品设定" },
                { "skills", "技能设定" },
                { "maps", "地图设定" }
            };

            var chineseType = settingTypeMap.ContainsKey(settingType.ToLower()) 
                ? settingTypeMap[settingType.ToLower()] 
                : $"{settingType}设定";

            return $"{SanitizeFileName(bookTitle)}_{chineseType}{fileExtension}";
        }

        /// <summary>
        /// 生成角色设定文件名
        /// 格式：书名_角色_角色名.扩展名
        /// </summary>
        public string GenerateCharacterFileName(string bookTitle, string characterName, string fileExtension = ".txt")
        {
            return $"{SanitizeFileName(bookTitle)}_角色_{SanitizeFileName(characterName)}{fileExtension}";
        }

        /// <summary>
        /// 生成时间线文件名
        /// 格式：书名_时间线_第X卷.扩展名 或 书名_总时间线.扩展名
        /// </summary>
        public string GenerateTimelineFileName(string bookTitle, int? volumeNumber = null, string fileExtension = ".txt")
        {
            if (volumeNumber.HasValue && volumeNumber.Value > 0)
            {
                return $"{SanitizeFileName(bookTitle)}_时间线_第{volumeNumber.Value:D2}卷{fileExtension}";
            }
            else
            {
                return $"{SanitizeFileName(bookTitle)}_总时间线{fileExtension}";
            }
        }

        /// <summary>
        /// 清理文件名中的非法字符
        /// </summary>
        public string SanitizeFileName(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return "未命名";

            var invalidChars = Path.GetInvalidFileNameChars();
            var sanitized = fileName;

            foreach (var invalidChar in invalidChars)
            {
                sanitized = sanitized.Replace(invalidChar, '_');
            }

            // 替换一些常见的特殊字符为中文全角字符
            sanitized = sanitized.Replace(":", "：");
            sanitized = sanitized.Replace("?", "？");
            sanitized = sanitized.Replace("*", "＊");
            sanitized = sanitized.Replace("<", "＜");
            sanitized = sanitized.Replace(">", "＞");
            sanitized = sanitized.Replace("|", "｜");
            sanitized = sanitized.Replace("/", "／");
            sanitized = sanitized.Replace("\\", "＼");

            // 移除连续的下划线
            sanitized = Regex.Replace(sanitized, "_+", "_");

            // 移除开头和结尾的下划线
            sanitized = sanitized.Trim('_', ' ');

            return string.IsNullOrEmpty(sanitized) ? "未命名" : sanitized;
        }

        /// <summary>
        /// 获取中文文件夹名称映射
        /// </summary>
        public Dictionary<string, string> GetChineseFolderNames()
        {
            return new Dictionary<string, string>(_chineseFolderNames);
        }

        /// <summary>
        /// 获取当前文件命名配置
        /// </summary>
        public FileNamingConfig GetCurrentConfig()
        {
            if (_currentConfig != null)
                return _currentConfig;

            try
            {
                if (File.Exists(_configPath))
                {
                    var json = File.ReadAllText(_configPath);
                    _currentConfig = FileNamingConfig.FromJson(json) ?? new FileNamingConfig();
                }
                else
                {
                    _currentConfig = new FileNamingConfig();
                    SaveConfig(_currentConfig);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载文件命名配置失败，使用默认配置");
                _currentConfig = new FileNamingConfig();
            }

            return _currentConfig;
        }

        /// <summary>
        /// 保存文件命名配置
        /// </summary>
        public void SaveConfig(FileNamingConfig config)
        {
            try
            {
                var directory = Path.GetDirectoryName(_configPath);
                if (!string.IsNullOrEmpty(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                config.UpdatedAt = DateTime.Now;
                var json = config.ToJson();
                File.WriteAllText(_configPath, json);

                _currentConfig = config;
                _logger.LogInformation("文件命名配置保存成功");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存文件命名配置失败");
                throw;
            }
        }

        /// <summary>
        /// 使用配置生成章节文件名
        /// </summary>
        public string GenerateChapterFileName(string bookTitle, int volumeNumber, string volumeName, int chapterNumber, string chapterTitle, string fileExtension, FileNamingConfig? config = null)
        {
            config ??= GetCurrentConfig();

            var template = config.ChapterNamingTemplate;
            var fileName = template
                .Replace("{BookTitle}", SanitizeFileName(bookTitle))
                .Replace("{VolumeNumber}", volumeNumber.ToString())
                .Replace("{VolumeNumber:D2}", volumeNumber.ToString("D2"))
                .Replace("{VolumeName}", SanitizeFileName(volumeName))
                .Replace("{ChapterNumber}", chapterNumber.ToString())
                .Replace("{ChapterNumber:D3}", chapterNumber.ToString("D3"))
                .Replace("{ChapterTitle}", SanitizeFileName(chapterTitle))
                .Replace("{Date}", DateTime.Now.ToString(config.DateFormat))
                .Replace("{Time}", DateTime.Now.ToString(config.TimeFormat));

            if (config.UseChineseNumbers)
            {
                fileName = fileName
                    .Replace($"第{volumeNumber:D2}卷", $"第{config.GetChineseNumber(volumeNumber)}卷")
                    .Replace($"第{chapterNumber:D3}章", $"第{config.GetChineseNumber(chapterNumber)}章");
            }

            return ApplyFileNameRules(fileName, fileExtension, config);
        }

        /// <summary>
        /// 使用配置生成大纲文件名
        /// </summary>
        public string GenerateOutlineFileName(string bookTitle, string outlineType, string fileExtension, FileNamingConfig? config = null)
        {
            config ??= GetCurrentConfig();

            var template = config.OutlineNamingTemplate;
            var fileName = template
                .Replace("{BookTitle}", SanitizeFileName(bookTitle))
                .Replace("{OutlineType}", SanitizeFileName(outlineType))
                .Replace("{Date}", DateTime.Now.ToString(config.DateFormat))
                .Replace("{Time}", DateTime.Now.ToString(config.TimeFormat));

            return ApplyFileNameRules(fileName, fileExtension, config);
        }

        /// <summary>
        /// 使用配置生成角色文件名
        /// </summary>
        public string GenerateCharacterFileName(string bookTitle, string characterName, string fileExtension, FileNamingConfig? config = null)
        {
            config ??= GetCurrentConfig();

            var template = config.CharacterNamingTemplate;
            var fileName = template
                .Replace("{BookTitle}", SanitizeFileName(bookTitle))
                .Replace("{CharacterName}", SanitizeFileName(characterName))
                .Replace("{Date}", DateTime.Now.ToString(config.DateFormat))
                .Replace("{Time}", DateTime.Now.ToString(config.TimeFormat));

            return ApplyFileNameRules(fileName, fileExtension, config);
        }

        /// <summary>
        /// 使用配置生成时间线文件名
        /// </summary>
        public string GenerateTimelineFileName(string bookTitle, int? volumeNumber, string fileExtension, FileNamingConfig? config = null)
        {
            config ??= GetCurrentConfig();

            var template = config.TimelineNamingTemplate;
            var fileName = template
                .Replace("{BookTitle}", SanitizeFileName(bookTitle))
                .Replace("{Date}", DateTime.Now.ToString(config.DateFormat))
                .Replace("{Time}", DateTime.Now.ToString(config.TimeFormat));

            if (volumeNumber.HasValue)
            {
                fileName = fileName
                    .Replace("{VolumeNumber}", volumeNumber.Value.ToString())
                    .Replace("{VolumeNumber:D2}", volumeNumber.Value.ToString("D2"));

                if (config.UseChineseNumbers)
                {
                    fileName = fileName.Replace($"第{volumeNumber.Value:D2}卷", $"第{config.GetChineseNumber(volumeNumber.Value)}卷");
                }
            }
            else
            {
                // 移除卷相关的占位符
                fileName = fileName
                    .Replace("_第{VolumeNumber:D2}卷", "")
                    .Replace("_{VolumeNumber:D2}卷", "")
                    .Replace("第{VolumeNumber:D2}卷_", "")
                    .Replace("第{VolumeNumber:D2}卷", "")
                    .Replace("_第{VolumeNumber}卷", "")
                    .Replace("_{VolumeNumber}卷", "")
                    .Replace("第{VolumeNumber}卷_", "")
                    .Replace("第{VolumeNumber}卷", "");
            }

            return ApplyFileNameRules(fileName, fileExtension, config);
        }

        /// <summary>
        /// 应用文件名规则
        /// </summary>
        private string ApplyFileNameRules(string fileName, string fileExtension, FileNamingConfig config)
        {
            // 清理文件名
            if (config.AutoSanitizeFileNames)
            {
                fileName = SanitizeFileName(fileName);
            }

            // 限制文件名长度
            if (fileName.Length > config.MaxFileNameLength)
            {
                fileName = fileName.Substring(0, config.MaxFileNameLength);
            }

            // 添加扩展名
            if (!string.IsNullOrEmpty(fileExtension) && !fileExtension.StartsWith("."))
            {
                fileExtension = "." + fileExtension;
            }

            return fileName + (fileExtension ?? config.DefaultFileExtension);
        }
    }
}
